package com.twb.code.gen.controller;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.StringWriter;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;

import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.google.common.base.Charsets;
import com.twb.code.gen.entity.twbCodeGen.TwbCodeGen;
import com.twb.code.gen.entity.twbCodeGen.dto.GetTwbCodeGenByIdDto;
import com.twb.code.gen.entity.twbCodeGen.dto.SearchDataDicKeyDto;
import com.twb.code.gen.entity.twbCodeGen.dto.SearchTableColumnsDto;
import com.twb.code.gen.entity.twbCodeGen.dto.SearchTableDto;
import com.twb.code.gen.entity.twbCodeGen.dto.SearchTwbCodeGenDto;
import com.twb.code.gen.entity.twbCodeGen.vo.SaveTwbCodeGenVo;
import com.twb.code.gen.entity.twbCodeGen.vo.SearchTwbCodeGenVo;
import com.twb.code.gen.entity.twbCodeGen.vo.UpdateTwbCodeGenByIdVo;
import com.twb.code.gen.service.ITwbCodeGenService;
import com.twb.core.base.Result;
import com.twb.core.base.controller.BaseController;
import com.twb.core.base.entity.TwbPageInfo;
import com.twb.core.security.annotation.Auth;
import com.twb.core.util.BeanUtils;
import com.twb.core.util.Results;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;

/**
 * @Title  TwbCodeGenController
 * @Description 代码生成配置
 * 
 * @author DSY
 * @date 2021-12-31 15:30:38
 */
@RestController
@RequestMapping("/gen/twbCodeGen")
@Api(tags = "代码生成配置", value = "TwbCodeGenController")
public class TwbCodeGenController extends BaseController {
	@Autowired
	ITwbCodeGenService twbCodeGenService;

	/**
	 * @Title  search
	 * @Description 分页查询
	 * @param vo
	 * @return
	 * @author DSY
	 * @date 2021-12-31 15:30:38
	 */
	@GetMapping("/search")
	@ApiOperation(value = "分页查询")
	public Result<TwbPageInfo<SearchTwbCodeGenDto>> search(SearchTwbCodeGenVo vo) {
		TwbPageInfo<SearchTwbCodeGenDto> result = twbCodeGenService.searchTwbCodeGen(vo);
		return Results.successWithData(result);
	}

	/**
	 * @Title  getById
	 * @Description 根据ID获取详情
	 * @param id
	 * @return
	 * @author DSY
	 * @date 2021-12-31 15:30:38
	 */
	@GetMapping("/getById")
	@ApiOperation(value = "根据ID获取详情")
	public Result<GetTwbCodeGenByIdDto> getById(
			@NotBlank @RequestParam @ApiParam(value = "主键", name = "id", required = true) String id) {
		TwbCodeGen twbCodeGen = twbCodeGenService.getById(id);
		if (twbCodeGen == null) {
			return Results.failure("数据不存在");
		}
		GetTwbCodeGenByIdDto dto = new GetTwbCodeGenByIdDto();
		BeanUtils.copyNotNullProperties(twbCodeGen, dto);
		return Results.successWithData(dto);
	}

	/**
	 * @Title  save
	 * @Description 保存信息
	 * @param vo
	 * @return
	 * @author DSY
	 * @date 2021-12-31 15:30:38
	 */
	@PostMapping("/save")
	@ApiOperation(value = "保存信息")
	public Result<String> save(@RequestBody @Valid SaveTwbCodeGenVo vo) {
		boolean result = twbCodeGenService.saveTwbCodeGen(vo);
		if (result) {
			return Results.success("保存成功");
		} else {
			return Results.failure("保存失败");
		}
	}

	/**
	 * @Title  updateById
	 * @Description 更新信息
	 * @param vo
	 * @return
	 * @author DSY
	 * @date 2021-12-31 15:30:38
	 */
	@Auth(verifyToken = true)
	@PutMapping("/updateById")
	@ApiOperation(value = "更新信息")
	public Result<String> updateById(@RequestBody @Valid UpdateTwbCodeGenByIdVo vo) {
		boolean result = twbCodeGenService.updateTwbCodeGenById(vo);
		if (result) {
			return Results.success("更新成功");
		} else {
			return Results.failure("更新失败");
		}
	}

	/**
	 * @Title  deleteById
	 * @Description 删除信息
	 * @param id
	 * @return
	 * @author DSY
	 * @date 2021-12-31 15:30:38
	 */
	@PostMapping("/deleteById")
	@ApiOperation(value = "删除信息")
	public Result<String> deleteById(
			@NotBlank @RequestParam @ApiParam(value = "主键", name = "id", required = true) String id) {
		boolean result = twbCodeGenService.deleteTwbCodeGenById(id);
		if (result) {
			return Results.success("删除成功");
		} else {
			return Results.failure("删除失败");
		}
	}

	/**
	 * @Title  deleteBatchByIds
	 * @Description 批量删除信息
	 * @param ids
	 * @return
	 * @author DSY
	 * @date 2021-12-31 15:30:38
	 */
	@PostMapping("/batchDeleteByIds")
	@ApiOperation(value = "批量删除信息")
	public Result<String> deleteBatchByIds(
			@NotBlank @RequestParam @ApiParam(value = "主键集合", name = "id", required = true) String ids) {
		boolean result = twbCodeGenService.deleteTwbCodeGenByIds(ids);
		if (result) {
			return Results.success("删除成功");
		} else {
			return Results.failure("删除失败");
		}
	}

	/**
	 * @Title searchTables
	 * @Description 查询所有表、视图
	 * @param queryLikeStr
	 * @return
	 * @author DHL
	 * @date 2022年1月29日 上午10:14:17
	 */
	@Auth(verifyURL = false)
	@GetMapping("/searchTables")
	@ApiOperation(value = "查询所有表、视图")
	public Result<List<SearchTableDto>> searchTables(String queryLikeStr) {
		List<SearchTableDto> result = twbCodeGenService.searchTables(queryLikeStr);
		return Results.successWithData(result);
	}

	/**
	 * @Title searchColumns
	 * @Description 查询列信息
	 * @param tableName
	 * @return
	 * @author DHL
	 * @date 2022年1月29日 上午10:14:55
	 */
	@Auth(verifyURL = false)
	@GetMapping("/searchColumns")
	@ApiOperation(value = "查询列信息")
	public Result<List<SearchTableColumnsDto>> searchColumns(String tableName) {
		List<SearchTableColumnsDto> result = twbCodeGenService.searchColumns(tableName);
		return Results.successWithData(result);
	}

	/**
	 * @Title searchDataDicKey
	 * @Description 查询数据字典key
	 * @return
	 * @author DHL
	 * @date 2022年1月29日 上午10:58:47
	 */
	@Auth(verifyURL = false)
	@GetMapping("/searchDataDicKey")
	@ApiOperation(value = "查询数据字典key")
	public Result<List<SearchDataDicKeyDto>> searchDataDicKey() {
		List<SearchDataDicKeyDto> result = twbCodeGenService.searchDataDicKey();
		return Results.successWithData(result);
	}

	/**
	 * @Title downloadZip
	 * @Description 打包下载zip文件
	 * @param response
	 * @param templates
	 * @throws IOException
	 * @author DSY
	 * @date 2022年2月2日 下午9:47:55
	 */
	@Auth(verifyURL = false)
	@GetMapping("/downloadZip")
	@ApiOperation(value = "打包下载")
	public void downloadZip(HttpServletResponse response, Map<String, String> templates) throws IOException {
		byte[] data = genZip(templates);
		response.reset();
		response.setHeader("Content-Disposition", "attachment; filename=\"twb.zip\"");
		response.addHeader("Content-Length", "" + data.length);
		response.setContentType("application/octet-stream; charset=UTF-8");
		IOUtils.write(data, response.getOutputStream());
	}

	/**
	 * @Title genZip
	 * @Description 生成zip
	 * @param templates
	 * @return
	 * @author DSY
	 * @date 2022年2月2日 下午9:43:11
	 */
	private byte[] genZip(Map<String, String> templates) {
		ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        ZipOutputStream zip = new ZipOutputStream(outputStream);
        generatorCode(templates, zip);
        IOUtils.closeQuietly(zip);
		return outputStream.toByteArray();
	}
	/**
	 * @Title generatorCode
	 * @Description 渲染文件模板
	 * @param templates
	 * @param zip
	 * @author DSY
	 * @date 2022年2月2日 下午9:43:24
	 */
	private void generatorCode(Map<String, String> templates,ZipOutputStream zip) {
		// 获取模板列表
		Set<String> keySet = templates.keySet();
		for (String key : keySet) {
			String template = templates.get(key);
			// 渲染模板
			StringWriter sw = new StringWriter();
			sw.append(template);
			try {
				// 添加到zip
				zip.putNextEntry(new ZipEntry(template));
				IOUtils.write(sw.toString(), zip, Charsets.UTF_8);
				zip.flush();
				zip.closeEntry();
				IOUtils.closeQuietly(zip);
			} catch (IOException e) {
//				log.error("渲染模板失败，表名：" + table.getTableName(), e);
			}
		}
	}
}